package com.xjscrm.console.chat.core.impl.staff;

import com.xjscrm.common.entity.MerchatChild;
import com.xjscrm.common.exception.BusinessException;
import com.xjscrm.console.chat.cache.CacheHolder;
import com.xjscrm.console.chat.core.ChatBaseMsgHandler;
import com.xjscrm.console.chat.enums.ChatMsgType;
import com.xjscrm.console.chat.enums.MQMsgType;
import com.xjscrm.console.chat.frame.recv.RStaffMsg;
import com.xjscrm.console.chat.frame.send.SResultMsg;
import com.xjscrm.console.chat.mq.MQSender;
import com.xjscrm.console.chat.mq.dto.SendMQDTO;
import com.xjscrm.console.chat.mq.dto.StaffOfflineDTO;
import com.xjscrm.console.chat.utils.ChannelUtils;
import com.xjscrm.console.entity.MerchatChildDeviceRelation;
import com.xjscrm.console.service.customer.chat.ChatTalkSessionService;
import com.xjscrm.console.service.customer.childUser.ChildMerchatService;
import com.xjscrm.console.service.customer.merchat.MerchatChildDeviceRelationService;
import com.xjscrm.console.service.customer.wwDevice.WwDeviceService;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author mingyang.chen create in 2024/3/12 09:41
 */
@Component
@Slf4j
public class ChatStaffOnlineMsgHandler extends ChatBaseMsgHandler<RStaffMsg> {

    @Autowired
    Environment environment;

    @Autowired
    private ChatTalkSessionService chatTalkSessionService;

    @Autowired
    private WwDeviceService wwDeviceService;

    @Autowired
    private ChildMerchatService childMerchatService;
    @Autowired
    private MerchatChildDeviceRelationService childDeviceRelationService;

    @Autowired
    private CacheHolder cacheHolder;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private WwDeviceService deviceService;

    @Override
    public Class<RStaffMsg> msgClass() {
        return RStaffMsg.class;
    }

    @Override
    public boolean basic() {
        return true;
    }

    @Override
    public SResultMsg doHandle(RStaffMsg content, ChannelHandlerContext ctx) {
        Long staffId = content.getStaffId();
        Long merId = content.getMerId();

        if (Objects.equals(merId, staffId)) {
            throw new BusinessException("主账号不允许操作");
        }

        String mqTag = environment.getProperty("mqTag");

        try {
            Channel staffChannel = cacheHolder.getStaffChannel(staffId);
            if (Objects.nonNull(staffChannel)) {
                if (!Objects.equals(staffChannel, ctx.channel())) {
                    ChannelUtils.setCloseAttr(staffChannel, "员工重复上班, 踢掉上次链接");
                    staffChannel.close();
                } else {
                    return SResultMsg.success(content, "员工已上班成功, 请勿重复上班");
                }
            } else {
                String staffChannelId = cacheHolder.getStaffChannelId(staffId);
                if (StringUtils.isNoneBlank(staffChannelId)) {
                    String[] channelIdArr = staffChannelId.split("-");
                    String channelId = channelIdArr[0];
                    String channelNodeTag = channelIdArr[1];

                    StaffOfflineDTO staffOfflineDTO = new StaffOfflineDTO(staffId, channelId, channelNodeTag);
                    staffOfflineDTO.setMerId(merId);

                    SendMQDTO sendMQDTO = new SendMQDTO();
                    sendMQDTO.setType(MQMsgType.staff_offline.getCode());
                    sendMQDTO.setData(staffOfflineDTO);

                    MQSender.sendMQMsg("XJ_WW_DISPATCH_HANDLE_TOPIC:" + channelNodeTag, sendMQDTO);

                    /*rocketMQTemplate.asyncSend("xj_staff_offline_topic:" + channelNodeTag, MessageBuilder.withPayload(staffOfflineDTO).build(), new SendCallback() {
                        @Override
                        public void onSuccess(SendResult sendResult) {
                            log.info("员工离线消息发送成功: {}", JSON.toJSONString(staffOfflineDTO));
                        }

                        @Override
                        public void onException(Throwable e) {
                            log.error("员工离线消息发送失败");
                        }
                    });*/
                    // 休眠
                    TimeUnit.SECONDS.sleep(1);
                }
            }

            /*MerchatChild merchatChild;
            List<WwDevice> devices = null;

            if (Objects.equals(staffId, merId)) {
                Merchant merchant = userService.getById(staffId);
                if (Objects.isNull(merchant)) {
                    throw new BusinessException("员工上班失败, 员工不存在");
                }
                devices = deviceService.listByMerId(merId);
            } else {
                merchatChild = childMerchatService.getById(merId, staffId);
                if (Objects.isNull(merchatChild)) {
                    throw new BusinessException("员工上班失败, 员工不存在");
                }
                List<MerchatChildDeviceRelation> staffRelDevices = merchatChildDeviceRelationService.listByStaffId(merId, staffId);
                if (ObjectUtils.isNotEmpty(staffRelDevices)) {
                    List<Long> deviceUniqueIds = staffRelDevices.stream().map(MerchatChildDeviceRelation::getRobotId).distinct().collect(Collectors.toList());
                    devices = wwDeviceService.getByIds(merId, deviceUniqueIds);
                }
            }*/
            MerchatChild byId = childMerchatService.getById(merId, staffId);
            if (Objects.isNull(byId)) {
                throw new BusinessException("员工不存在");
            }

            cacheHolder.setStaffSessionCount(merId, staffId, byId.getChatLimitCount());

            cacheHolder.setStaffChannel(staffId, ctx.channel());
            //
            cacheHolder.setStaffChannelId(staffId, ctx.channel().id().asShortText() + "-" + mqTag);
            cacheHolder.setStaffTag(staffId, mqTag);

            List<MerchatChildDeviceRelation> childDeviceRelations = childDeviceRelationService.listByStaffId(merId, staffId);
            for (MerchatChildDeviceRelation item : childDeviceRelations) {
                chatTalkSessionService.fetchAndPushOrderSession(merId, staffId, item.getRobotId());
            }
            //
            ChannelUtils.setStaff(ctx.channel(), staffId);
            return SResultMsg.success(content, "员工上班成功", ChatMsgType.s_staff_online);
        } catch (Exception e) {
            log.error("员工上线失败", e);
            cacheHolder.delStaffChannel(staffId);
            throw new BusinessException("员工上线失败");
        }
    }

    @Override
    public ChatMsgType msgType() {
        return ChatMsgType.r_staff_online;
    }
}
